﻿using System;
using System.Linq;

using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;

using Supremacy.Annotations;
using Supremacy.Entities;
using Supremacy.Resources;

namespace SupremacyEditor.RacesModule
{
    public class RacesModule : IModule
    {
        #region Fields
        private readonly IUnityContainer _container;
        private readonly IEditorController _editorController;
        private readonly IRegionManager _regionManager;
        private readonly IResourceManagerService _resourceManagerService;
        private IRaceDatabaseController _controller;
        #endregion

        #region Constructors
        public RacesModule(
            [NotNull] IUnityContainer container,
            [NotNull] IEditorController editorController,
            [NotNull] IRegionManager regionManager,
            [NotNull] IResourceManagerService resourceManagerService)
        {
            if (container == null)
                throw new ArgumentNullException("container");
            if (editorController == null)
                throw new ArgumentNullException("editorController");
            if (regionManager == null)
                throw new ArgumentNullException("regionManager");
            if (resourceManagerService == null)
                throw new ArgumentNullException("resourceManagerService");
            _container = container;
            _resourceManagerService = resourceManagerService;
            _editorController = editorController;
            _regionManager = regionManager;
        }
        #endregion

        #region Methods
        protected void LoadRaceDatabase()
        {
            var raceDatabase = RaceDatabase.Load();
            _container.Resolve<IGameDataModel>().Races.AddRange(
                raceDatabase
                    .Select(
                    o => new RacePresentationModel(
                             _editorController,
                             _resourceManagerService,
                             o))
                    .Cast<IRacePresentationModel>());
        }

        protected void RegisterViewsAndServices()
        {
            _container.RegisterType<IRaceDatabaseView, RaceDatabaseView>(new ContainerControlledLifetimeManager());
            _container.RegisterType<IRaceDatabaseController, RaceDatabaseController>(new ContainerControlledLifetimeManager());
            _regionManager.RegisterViewWithRegion(RegionNames.HomeTabModulesGroup, () => new RacesDatabaseRibbonButton());
        }

        private void OnReloadModuleData(object sender, EventArgs e)
        {
            LoadRaceDatabase();
        }
        #endregion

        #region IModule Members
        public void Initialize()
        {
            RegisterViewsAndServices();

            _controller = _container.Resolve<IRaceDatabaseController>();
            _editorController.ReloadModuleData += OnReloadModuleData;

            LoadRaceDatabase();

            _controller.Run();
        }
        #endregion
    }
}